package com.huifer.wgx.service.impl;

import com.huifer.wgx.model.FieldPointEntity;
import com.huifer.wgx.model.FileEntity;
import com.huifer.wgx.model.RtkPointEntity;
import com.huifer.wgx.pojo.CsvFieldPoint;
import com.huifer.wgx.repository.FieldPointRepository;
import com.huifer.wgx.repository.FileRepository;
import com.huifer.wgx.repository.RtkPointRepository;
import com.huifer.wgx.service.FieldPointService;
import com.huifer.wgx.spec.CommonSpec;
import com.huifer.wgx.utlis.CsvUtil;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

/**
 * <p>Title : FieldPointServiceImpl </p>
 * <p>Description : </p>
 *
 * @author huifer
 * @date 2019-03-20
 */
@Service
public class FieldPointServiceImpl implements FieldPointService {

    @Autowired
    private FieldPointRepository fieldPointRepository;
    @Autowired
    private FileRepository fileRepository;
    @Autowired
    private RtkPointRepository rtkPointRepository;

    /**
     * 添加一个外业采集点
     *
     * @param fieldPointName 外业采集点点名
     * @param fieldPointManholeCoverType 井盖类型
     * @param fieldPointIsmesh 有无网罩
     * @param fieldPointDeep 井深单位米
     * @param fieldPointSize 井盖尺寸
     * @param personnelId 采集人id
     * @param workId 工程id
     * @return FieldPointEntity
     */
    @Override
    public FieldPointEntity saveOneFieldPoint(String fieldPointName,
            String fieldPointManholeCoverType, String fieldPointIsmesh, BigDecimal fieldPointDeep,
            String fieldPointSize, Long personnelId, Long workId) {
        FieldPointEntity fp = new FieldPointEntity();
        fp.setFieldPointName(fieldPointName);
        fp.setFieldPointManholeCoverType(fieldPointManholeCoverType);
        fp.setFieldPointIsmesh(fieldPointIsmesh);
        fp.setFieldPointDeep(fieldPointDeep);
        fp.setFieldPointSize(fieldPointSize);
        // 关联关系绑定
        fp.setPersonnelId(personnelId);
        fp.setWorkId(workId);
        return fieldPointRepository.save(fp);
    }

    /**
     * 查询具体的csv文件 构造 FieldPointEntity
     *
     * @param personnelId 上传id
     * @param workid 工程id
     * @param filename 文件名
     * @return FieldPointEntity
     */
    @Override
    public List<FieldPointEntity> createList(Long personnelId, Long workid, String filename) {
        try {
        FileEntity fileEntity = CommonSpec.fileSpec(fileRepository, personnelId, workid, filename);

        Specification<RtkPointEntity> r = getRtkPointEntitySpecification(personnelId, workid);
        List<RtkPointEntity> allRtk = rtkPointRepository.findAll(r);


            Iterator<CsvFieldPoint> fieldPointIterator = CsvUtil
                    .csvFieldPointReader(fileEntity.getcPath());
            List<FieldPointEntity> rs = new ArrayList<>();
            while (fieldPointIterator.hasNext()) {
                CsvFieldPoint next = fieldPointIterator.next();
                FieldPointEntity entity = new FieldPointEntity();
                // 设置csv中属性
                entity.setFieldPointName(next.getName());
                entity.setFieldPointManholeCoverType(next.getCoverType());
                entity.setFieldPointIsmesh(next.getIsMesh());
                entity.setFieldPointSize(next.getSize());
                entity.setFieldPointDeep(next.getDeep());
                // 设置表关联属性
                entity.setPersonnelId(personnelId);
                entity.setWorkId(workid);
                entity.setFiledId(fileEntity.getFileId());
                entity.setRtkId(getRtkId(allRtk, entity));

                rs.add(entity);
            }
            return rs;
        } catch (Exception e) {
            throw new RuntimeException("csv 解析异常");
        }
    }

    /**
     * RTK查询条件
     *
     * @param personnelId 采集人id
     * @param workid 工程id
     * @return 查询条件
     */
    private Specification<RtkPointEntity> getRtkPointEntitySpecification(Long personnelId,
            Long workid) {
        return (Specification<RtkPointEntity>) (root, criteriaQuery, criteriaBuilder) -> criteriaBuilder
                .and(
                        criteriaBuilder.equal(root.get("workId"), workid),
                        criteriaBuilder.equal(root.get("personnelId"), personnelId)
                );
    }

    /**
     * 根据采集人id查询所有
     *
     * @param personnelId 采集人id
     * @param pageNum 页面号
     * @param pageSize 页面大小
     * @return 外业采集点列表
     */
    @Override
    public Page<FieldPointEntity> findByPersonnelId(Long personnelId, Integer pageNum,
            Integer pageSize) {
        Specification<FieldPointEntity> spec = (Specification<FieldPointEntity>) (root, criteriaQuery, criteriaBuilder) -> criteriaBuilder
                .equal(root.get("personnelId"), personnelId);
        return getFpointEntitys(pageNum, pageSize, spec);
    }

    /**
     * 获取rtkid
     *
     * @param allRtk rtk列表
     * @param fieldPointEntity 外业点
     * @return rtk id
     */
    private Long getRtkId(List<RtkPointEntity> allRtk, FieldPointEntity fieldPointEntity) {
        for (int i = 0; i < allRtk.size(); i++) {
            boolean equals = allRtk.get(i).getRtkName()
                    .equals(fieldPointEntity.getFieldPointName());
            if (equals) {
                return allRtk.get(i).getRtkId();
            }
        }
        return null;
    }

    /**
     * 保存外业采集点
     *
     * @param fieldPointEntityList 外业采集点列表
     * @return 外业采集点列表
     */
    @Override
    public List<FieldPointEntity> saveFieldPoint(List<FieldPointEntity> fieldPointEntityList) {
        try {
            return fieldPointRepository.saveAll(fieldPointEntityList);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 查询所有
     *
     * @param pageNum 页面号
     * @param pageSize 页面大小
     * @return 外业采集点列表
     */
    @Override
    public Page<FieldPointEntity> findAll(Integer pageNum, Integer pageSize) {
        return getFpointEntitys(pageNum, pageSize, null);
    }

    /**
     * 根据工程id查询所有
     *
     * @param pageNum 页面号
     * @param pageSize 页面大小
     * @param workId 工程id
     * @return 外业采集点列表
     */
    @Override
    public Page<FieldPointEntity> findByWorkId(Integer pageNum, Integer pageSize, Long workId) {
        Specification<FieldPointEntity> specV = (Specification<FieldPointEntity>) (root, criteriaQuery, criteriaBuilder) -> criteriaBuilder
                .equal(root.get("workId"), workId);
        return getFpointEntitys(pageNum, pageSize, specV);

    }

    /**
     * 获取外业采集点列表
     *
     * @param pageNum 页面号
     * @param pageSize 页面大小
     * @param specV 过滤条件
     * @return 外业采集点列表
     */
    private Page<FieldPointEntity> getFpointEntitys(Integer pageNum, Integer pageSize,
            Specification<FieldPointEntity> specV) {
        Sort sort = new Sort(Direction.DESC, "fieldPointId");
        Pageable pageable = PageRequest.of(pageNum - 1, pageSize, sort);
        return fieldPointRepository.findAll(specV, pageable);
    }
}
